from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, 
                             QPushButton, QTableWidget, QTableWidgetItem,
                             QComboBox, QFrame, QGroupBox, QGridLayout, QTabWidget,
                             QDialog, QLineEdit, QMessageBox, QFormLayout)
from PyQt6.QtCore import Qt, QTimer, pyqtSignal
import threading
import time
from PyQt6.QtGui import QFont
from .qr_code_dialog import QRCodeDialog
from config.proxy_config import proxy_config
from http_client import http_client
from websocket_client import websocket_client
from database import db_manager
from PyQt6.QtWidgets import QHeaderView
from utils.style_manager import StyleManager

class ProxySettingsDialog(QDialog):
    """代理设置对话框"""
    
    def __init__(self, parent=None, edit_name: str = "", default_name: str = ""):
        super().__init__(parent)
        self.edit_name = edit_name  # 要编辑的代理配置名称
        self.default_name = default_name  # 默认名称
        self.setWindowTitle("代理设置")
        self.setFixedSize(400, 250)
        self.setModal(True)
        self.setup_ui()
        self.load_current_settings()
        
    def setup_ui(self):
        layout = QVBoxLayout(self)
        layout.setSpacing(15)
        
        # 表单布局
        form_layout = QFormLayout()
        
        # 配置名称输入框
        self.name_edit = QLineEdit()
        self.name_edit.setPlaceholderText("例如: 公司代理")
        form_layout.addRow("配置名称:", self.name_edit)
        
        # 代理IP输入框
        self.proxy_ip_edit = QLineEdit()
        self.proxy_ip_edit.setPlaceholderText("例如: 192.168.1.100:8080")
        form_layout.addRow("代理IP:", self.proxy_ip_edit)
        
        # 代理用户名输入框
        self.proxy_user_edit = QLineEdit()
        self.proxy_user_edit.setPlaceholderText("代理用户名（可选）")
        form_layout.addRow("代理用户:", self.proxy_user_edit)
        
        # 代理密码输入框
        self.proxy_password_edit = QLineEdit()
        self.proxy_password_edit.setPlaceholderText("代理密码（可选）")
        self.proxy_password_edit.setEchoMode(QLineEdit.EchoMode.Password)
        form_layout.addRow("代理密码:", self.proxy_password_edit)
        
        layout.addLayout(form_layout)
        
        # 按钮布局
        button_layout = QHBoxLayout()
        
        save_btn = QPushButton("保存")
        save_btn.clicked.connect(self.save_settings)
        button_layout.addWidget(save_btn)
        
        cancel_btn = QPushButton("取消")
        cancel_btn.clicked.connect(self.reject)
        button_layout.addWidget(cancel_btn)
        
        layout.addLayout(button_layout)
        
    def load_current_settings(self):
        """加载当前代理设置"""
        if self.edit_name:
            # 编辑现有配置
            settings = proxy_config.get_proxy_by_name(self.edit_name)
            if settings:
                self.name_edit.setText(settings.get("name", ""))
                self.proxy_ip_edit.setText(settings.get("ProxyIp", ""))
                self.proxy_user_edit.setText(settings.get("ProxyUser", ""))
                self.proxy_password_edit.setText(settings.get("ProxyPassword", ""))
        else:
            # 新建配置，清空所有字段
            self.name_edit.clear()
            self.proxy_ip_edit.clear()
            self.proxy_user_edit.clear()
            self.proxy_password_edit.clear()
            
            # 如果有默认名称，预填充
            if self.default_name:
                self.name_edit.setText(self.default_name)
    
    def save_settings(self):
        """保存代理设置"""
        name = self.name_edit.text().strip()
        proxy_ip = self.proxy_ip_edit.text().strip()
        proxy_user = self.proxy_user_edit.text().strip()
        proxy_password = self.proxy_password_edit.text().strip()
        
        if not name:
            QMessageBox.warning(self, "验证失败", "配置名称不能为空")
            return
        
        # 验证设置
        is_valid, message = proxy_config.validate_proxy_settings(proxy_ip, proxy_user, proxy_password)
        if not is_valid:
            QMessageBox.warning(self, "验证失败", message)
            return
        
        # 保存设置
        if proxy_config.save_proxy_settings(proxy_ip, proxy_user, proxy_password, name):
            QMessageBox.information(self, "成功", "代理设置已保存")
            self.accept()
        else:
            QMessageBox.critical(self, "错误", "保存代理设置失败")

class AccountPanel(QWidget):
    # 定义信号
    heartbeat_result_ready = pyqtSignal(int, str, bool)  # row, user_name, is_online
    logout_result_ready = pyqtSignal(int, str, bool)  # row, user_name, success
    wake_up_result_ready = pyqtSignal(int, str, bool)  # row, user_name, success
    delete_result_ready = pyqtSignal(int, str, bool)  # row, user_name, success
    qr_check_result_ready = pyqtSignal(int, str, bool)  # row, user_name, success
    qr_check_timer_ready = pyqtSignal(str, int, str, int)  # user_name, row, uuid, expired_time
    
    def __init__(self):
        super().__init__()
        self.setFixedWidth(400)
        self.setup_ui()
        
        # 初始化时加载代理设置
        self.update_proxy_combo()
            
        # 心跳定时器，每5秒触发
        self.heartbeat_timer = QTimer(self)
        self.heartbeat_timer.timeout.connect(self.send_heartbeat)
        self.heartbeat_timer.start(5 * 1000)
        
        # WebSocket状态显示更新定时器，每10秒更新一次状态显示
        self.websocket_timer = QTimer(self)
        self.websocket_timer.timeout.connect(self.manage_websocket_connections)
        self.websocket_timer.start(10 * 1000)
        
        # 连接信号
        self.heartbeat_result_ready.connect(self.on_heartbeat_result)
        self.logout_result_ready.connect(self.on_logout_result)
        self.wake_up_result_ready.connect(self.on_wake_up_result)
        self.delete_result_ready.connect(self.on_delete_result)
        self.qr_check_result_ready.connect(self.on_qr_check_result)
        self.qr_check_timer_ready.connect(self.on_qr_check_timer_ready)
        
        # 连接WebSocket的群邀请完成信号
        websocket_client.consent_finished.connect(self.on_consent_finished)
        
        # 二维码状态检查定时器
        self.qr_check_timers = {}  # {user_name: QTimer}
        self.qr_check_data = {}  # {user_name: {'row': row, 'uuid': uuid, 'start_time': time}}
        
    def setup_ui(self):
        layout = QVBoxLayout(self)
        layout.setContentsMargins(10, 10, 10, 10)
        layout.setSpacing(10)
        
        # 扫码登录按钮
        scan_login_btn = QPushButton("扫码登录")
        scan_login_btn.setFixedHeight(40)
        scan_login_btn.clicked.connect(self.show_qr_code_dialog)
        layout.addWidget(scan_login_btn)
        
        # 接口设置区域
        api_group = QGroupBox("接口设置")
        api_layout = QGridLayout(api_group)
        api_layout.addWidget(QLabel("二维码接口:"), 0, 0)

        self.api_combo = QComboBox()
        self.api_combo.addItems(["Mac", "Car"])
        self.api_combo.setCurrentText("Mac")  # 默认选择Mac接口
        api_layout.addWidget(self.api_combo, 0, 1)
        
        layout.addWidget(api_group)
        
        # 代理设置区域
        proxy_group = QGroupBox("代理设置")
        proxy_layout = QGridLayout(proxy_group)
        proxy_layout.addWidget(QLabel("代理:"), 0, 0)

        self.proxy_combo = QComboBox()
        proxy_layout.addWidget(self.proxy_combo, 0, 1)

        add_btn = QPushButton("添加")
        add_btn.clicked.connect(self.add_proxy_settings)
        proxy_layout.addWidget(add_btn, 0, 2)
        
        edit_btn = QPushButton("编辑")
        edit_btn.clicked.connect(self.edit_proxy_settings)
        proxy_layout.addWidget(edit_btn, 0, 3)
        
        delete_btn = QPushButton("删除")
        delete_btn.clicked.connect(self.delete_proxy_settings)
        proxy_layout.addWidget(delete_btn, 0, 4)
        
        layout.addWidget(proxy_group)
        
        # 账号统计
        stats_frame = QFrame()
        stats_layout = QHBoxLayout(stats_frame)
        
        # 创建统计标签
        self.total_label = QLabel("总数: 0")
        self.online_label = QLabel("在线: 0")
        self.offline_label = QLabel("离线: 0")
        
        # 设置样式
        StyleManager.set_label_style(self.total_label, "status-muted")
        StyleManager.set_label_style(self.online_label, "status-success")
        StyleManager.set_label_style(self.offline_label, "status-danger")
        
        stats_layout.addWidget(self.total_label)
        stats_layout.addWidget(self.online_label)
        stats_layout.addWidget(self.offline_label)
        
        # 添加WebSocket连接状态显示
        self.websocket_status_label = QLabel("WebSocket: 未连接")
        StyleManager.set_label_style(self.websocket_status_label, "status-muted")
        stats_layout.addWidget(self.websocket_status_label)
        
        layout.addWidget(stats_frame)
        
        # 账号列表表格 - 带标签页
        account_group = QGroupBox("账号列表")
        account_layout = QVBoxLayout(account_group)
        
        # 创建标签页
        account_tab_widget = QTabWidget()
        
        # 账号标签页
        account_tab = QWidget()
        account_tab_layout = QVBoxLayout(account_tab)
        
        self.account_table = QTableWidget()
        self.account_table.verticalHeader().setVisible(False)
        self.account_table.setColumnCount(5)
        self.account_table.setHorizontalHeaderLabels([
            "No", "昵称", "备注", "状态", "关码/重"
        ])
        
        # 设置表格撑满容器
        self.account_table.horizontalHeader().setStretchLastSection(True)
        self.account_table.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode.ResizeToContents)
        
        # 设置表格选择行为
        self.account_table.setSelectionBehavior(QTableWidget.SelectionBehavior.SelectRows)
        self.account_table.setSelectionMode(QTableWidget.SelectionMode.SingleSelection)
        
        # 允许点击空白处取消选择
        self.account_table.setFocusPolicy(Qt.FocusPolicy.StrongFocus)
        # 设置表格可以接受鼠标事件
        self.account_table.setMouseTracking(True)
        
        # 设置只有双击才能编辑，防止意外编辑
        self.account_table.setEditTriggers(QTableWidget.EditTrigger.DoubleClicked)
        
        # 连接表格选择变化事件
        self.account_table.itemSelectionChanged.connect(self.on_account_selection_changed)
        # 连接鼠标点击事件，处理点击空白处取消选择
        self.account_table.mousePressEvent = self.account_table_mouse_press_event
        # 连接item编辑完成事件，处理备注保存
        self.account_table.itemChanged.connect(self.on_account_item_changed)
        
        account_tab_layout.addWidget(self.account_table)
        account_tab_widget.addTab(account_tab, "账号")
        
        # 号池标签页
        pool_tab = QWidget()
        pool_tab_layout = QVBoxLayout(pool_tab)
        pool_tab_layout.addWidget(QLabel("号池功能区域"))
        account_tab_widget.addTab(pool_tab, "号池")
        
        account_layout.addWidget(account_tab_widget)
        
        # 添加操作按钮
        button_layout = QHBoxLayout()
        
        # 唤醒登录按钮
        self.wake_up_btn = QPushButton("唤醒登录")
        self.wake_up_btn.setFixedHeight(35)
        self.wake_up_btn.clicked.connect(self.wake_up_selected_account)
        self.wake_up_btn.setEnabled(False)  # 初始状态禁用
        StyleManager.set_button_style(self.wake_up_btn, "info")
        button_layout.addWidget(self.wake_up_btn)
        
        # 退出登录按钮
        self.logout_btn = QPushButton("退出登录")
        self.logout_btn.setFixedHeight(35)
        self.logout_btn.clicked.connect(self.logout_selected_account)
        self.logout_btn.setEnabled(False)  # 初始状态禁用
        StyleManager.set_button_style(self.logout_btn, "warning")
        button_layout.addWidget(self.logout_btn)
        
        # 删除账号按钮
        self.delete_btn = QPushButton("删除账号")
        self.delete_btn.setFixedHeight(35)
        self.delete_btn.clicked.connect(self.delete_selected_account)
        self.delete_btn.setEnabled(False)  # 初始状态禁用
        StyleManager.set_button_style(self.delete_btn, "danger")
        button_layout.addWidget(self.delete_btn)
        button_layout.addStretch()
        account_layout.addLayout(button_layout)
        
        layout.addWidget(account_group)
        
        # 初始化账号表格数据
        self.update_account_table()
        # 更新统计信息
        self.update_stats()
        
    def show_qr_code_dialog(self):
        """显示二维码登录对话框"""
        # 获取当前选择的代理名称和接口名称
        current_proxy_name = self.get_current_proxy_name()
        current_api_name = self.get_current_api_name()
        dialog = QRCodeDialog(self)
        # 传递当前代理名称和接口名称给二维码对话框
        dialog.get_qr_code(current_proxy_name, current_api_name)
        
        # 执行对话框并获取结果
        if dialog.exec() == QDialog.DialogCode.Accepted:
            # 获取登录信息
            login_info = dialog.get_login_info()
            if login_info:
                print(f"登录成功！用户信息: {login_info}")
                
                # 保存用户信息：userName、nickName、alias
                user_name = login_info.get('userName', '')
                nick_name = login_info.get('nickName', '')
                alias = login_info.get('alias', '')
                bind_mobile = login_info.get('bindMobile', '')
                
                # 添加代理信息到登录信息中
                login_info['proxy_name'] = current_proxy_name
                
                # 保存到数据库
                if db_manager.insert_user_account(login_info):
                    print(f"用户信息已保存到数据库: {user_name}")
                else:
                    print(f"保存用户信息到数据库失败: {user_name}")
                
                # 更新账号表格
                self.update_account_table()
                # 更新统计信息
                self.update_stats()
                
                # 立即为新登录的账号建立WebSocket连接（在子线程中执行）
                if user_name:
                    thread = threading.Thread(
                        target=self._connect_websocket_for_new_user,
                        args=(user_name,)
                    )
                    thread.daemon = True
                    thread.start()
                
                # 显示登录成功信息
                success_message = f"登录成功！\n\n用户信息：\n"
                if user_name:
                    success_message += f"用户名: {user_name}\n"
                if nick_name:
                    success_message += f"昵称: {nick_name}\n"
                if alias:
                    success_message += f"微信号: {alias}\n"
                if bind_mobile:
                    success_message += f"手机号: {bind_mobile}\n"
                success_message += f"\n用户信息已保存到数据库并更新到账号列表。\nWebSocket连接已建立。"
                
                QMessageBox.information(self, "登录成功", success_message)
                
            else:
                print("登录成功但未获取到用户信息")
                QMessageBox.warning(self, "登录失败", "登录成功但未获取到用户信息")
        else:
            print("用户取消了登录")
    
    def add_proxy_settings(self):
        """添加代理设置"""
        # 获取当前代理选择的名称作为默认名称
        current_proxy = self.proxy_combo.currentText()
        default_name = ""
        if current_proxy.startswith("代理:"):
            default_name = current_proxy.replace("代理: ", "")
        
        dialog = ProxySettingsDialog(self, default_name=default_name)
        if dialog.exec() == QDialog.DialogCode.Accepted:
            # 更新代理下拉框
            self.update_proxy_combo()
            # 如果这是第一个代理配置，自动选择它
            if self.proxy_combo.count() == 1:
                self.proxy_combo.setCurrentIndex(0)
            QMessageBox.information(self, "成功", "代理设置已添加")
    
    def edit_proxy_settings(self):
        """编辑代理设置"""
        current_text = self.proxy_combo.currentText()
        
        if not current_text or current_text == "请选择代理":
            QMessageBox.information(self, "提示", "请先选择要编辑的代理配置")
            return
        
        # 从显示文本中提取代理名称
        proxy_name = current_text.replace("代理: ", "")
        
        # 打开编辑对话框
        dialog = ProxySettingsDialog(self, edit_name=proxy_name)
        if dialog.exec() == QDialog.DialogCode.Accepted:
            # 更新代理下拉框
            self.update_proxy_combo()
            # 重新选择当前编辑的代理
            for i in range(self.proxy_combo.count()):
                if self.proxy_combo.itemText(i) == f"代理: {proxy_name}":
                    self.proxy_combo.setCurrentIndex(i)
                    break
            QMessageBox.information(self, "成功", "代理设置已更新")
    
    def delete_proxy_settings(self):
        """删除代理设置"""
        current_text = self.proxy_combo.currentText()
        
        if not current_text:
            QMessageBox.information(self, "提示", "当前没有可删除的代理配置")
            return
        
        # 从显示文本中提取代理名称
        proxy_name = current_text.replace("代理: ", "")
        
        reply = QMessageBox.question(
            self, 
            "确认删除", 
            f"确定要删除代理配置 '{proxy_name}' 吗？",
            QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
        )
        
        if reply == QMessageBox.StandardButton.Yes:
            if proxy_config.delete_proxy_settings(proxy_name):
                self.update_proxy_combo()
                QMessageBox.information(self, "成功", f"代理配置 '{proxy_name}' 已删除")
            else:
                QMessageBox.critical(self, "错误", "删除代理设置失败")
    
    def update_proxy_combo(self):
        """更新代理下拉框"""
        # 更新代理下拉框
        self.proxy_combo.clear()
        
        # 获取所有代理配置
        proxy_names = proxy_config.get_all_proxy_names()
        for name in proxy_names:
            self.proxy_combo.addItem(f"代理: {name}")
    
    def get_current_proxy_name(self) -> str:
        """获取当前选择的代理名称"""
        current_text = self.proxy_combo.currentText()
        # 如果代理选择的是代理配置，返回代理名称
        if current_text.startswith("代理:"):
            return current_text.replace("代理: ", "")
        # 否则返回空字符串（使用默认设置）
        return ""
    
    def get_current_api_name(self) -> str:
        """获取当前选择的接口名称"""
        display_text = self.api_combo.currentText()
        # 将显示名称转换为实际接口名
        if display_text == "Car":
            return "get_qr_code_car"
        else:
            return "get_qr_code_mac"  # 默认返回mac接口
    
    def update_account_table(self):
        """更新账号表格数据"""
        try:
            # 从数据库获取所有账号
            accounts = db_manager.get_all_accounts()
            
            # 设置表格行数
            self.account_table.setRowCount(len(accounts))
            
            # 填充表格数据
            for row, account in enumerate(accounts):
                # 序号（不可编辑）
                no_item = QTableWidgetItem(str(row + 1))
                no_item.setFlags(no_item.flags() & ~Qt.ItemFlag.ItemIsEditable)
                self.account_table.setItem(row, 0, no_item)
                
                # 昵称（不可编辑）
                nick_name = account.get('nick_name', '')
                nick_item = QTableWidgetItem(nick_name)
                nick_item.setFlags(nick_item.flags() & ~Qt.ItemFlag.ItemIsEditable)
                self.account_table.setItem(row, 1, nick_item)
                
                # 备注（可编辑） - 显示微信号，但允许用户修改为自定义备注
                alias = account.get('alias', '')
                remark_item = QTableWidgetItem(alias)
                # 备注列保持可编辑，不移除ItemIsEditable标志
                self.account_table.setItem(row, 2, remark_item)
                
                # 状态（不可编辑）——默认离线，等待心跳更新
                status_item = QTableWidgetItem("离线")
                status_item.setFlags(status_item.flags() & ~Qt.ItemFlag.ItemIsEditable)
                status_item.setForeground(Qt.GlobalColor.red)
                self.account_table.setItem(row, 3, status_item)
                
                # 关码/重（不可编辑）
                action_item = QTableWidgetItem("-")
                action_item.setFlags(action_item.flags() & ~Qt.ItemFlag.ItemIsEditable)
                self.account_table.setItem(row, 4, action_item)
            
            # 调整列宽
            self.account_table.resizeColumnsToContents()
            
            print(f"账号表格已更新，共 {len(accounts)} 个账号")
            
            # 更新统计信息
            self.update_stats()
            
        except Exception as e:
            print(f"更新账号表格失败: {e}")
    
    def update_stats(self):
        """更新统计信息"""
        try:
            # 基于当前表格显示统计，默认离线，心跳更新后实时变化
            total_count = self.account_table.rowCount()
            online_count = 0
            offline_count = 0

            for row in range(total_count):
                item = self.account_table.item(row, 3)
                text = item.text() if item else "离线"
                if text == "在线":
                    online_count += 1
                else:
                    offline_count += 1

            # 更新标签显示
            self.total_label.setText(f"总数: {total_count}")
            self.online_label.setText(f"在线: {online_count}")
            self.offline_label.setText(f"离线: {offline_count}")

        except Exception as e:
            print(f"更新统计信息失败: {e}")
    
    def send_heartbeat(self):
        """定时发送心跳包，更新账号状态"""
        # 在子线程中执行网络请求
        thread = threading.Thread(target=self._send_heartbeat_worker)
        thread.daemon = True
        thread.start()
    
    def _send_heartbeat_worker(self):
        """在子线程中执行心跳包检测"""
        row_count = self.account_table.rowCount()
        if row_count == 0:
            return
            
        # 从数据库获取所有账号信息
        accounts = db_manager.get_all_accounts()
        if len(accounts) != row_count:
            print(f"警告：数据库账号数量({len(accounts)})与表格行数({row_count})不匹配")
            return
            
        for row, account in enumerate(accounts):
            # 使用数据库中的userName字段作为心跳包参数
            user_name = account.get('user_name', '')
            if not user_name:
                print(f"警告：第{row+1}行账号缺少userName字段")
                continue
                
            try:
                resp = http_client.post_heartbeat(user_name)
                is_online = resp.get("Success", False) and resp.get("Code", -1) == 0
                
                # 如果心跳检测失败，只记录状态，不自动唤醒
                if not is_online:
                    print(f"账号 {user_name} 心跳检测失败，状态为离线")
                        
            except Exception as e:
                is_online = False
                
            # 使用信号更新UI（在主线程中执行）
            self.heartbeat_result_ready.emit(row, user_name, is_online)
    
    def on_heartbeat_result(self, row: int, user_name: str, is_online: bool):
        """处理心跳包检测结果（在主线程中执行）"""
        # 更新表格状态显示
        status_item = QTableWidgetItem("在线" if is_online else "离线")
        status_item.setFlags(status_item.flags() & ~Qt.ItemFlag.ItemIsEditable)  # 设置不可编辑
        status_item.setForeground(Qt.GlobalColor.green if is_online else Qt.GlobalColor.red)
        self.account_table.setItem(row, 3, status_item)
        
        # 同步数据库
        db_manager.update_account_status(user_name, 1 if is_online else 0)
        
        # 更新统计信息
        self.update_stats()
        
        # 根据在线状态管理WebSocket连接
        if is_online:
            # 如果账号在线但未建立WebSocket连接，则建立连接
            if not http_client.is_websocket_connected(user_name):
                try:
                    http_client.connect_websocket(
                        user_name,
                        message_callback=self.on_websocket_message,
                        status_callback=self.on_websocket_status_changed
                    )
                    print(f"账号 {user_name} 上线，已建立WebSocket连接")
                except Exception as e:
                    print(f"为上线账号建立WebSocket连接失败: {user_name}, 错误: {e}")
        else:
            # 如果账号离线但仍有WebSocket连接，则断开连接
            if http_client.is_websocket_connected(user_name):
                try:
                    http_client.disconnect_websocket(user_name)
                    print(f"账号 {user_name} 离线，已断开WebSocket连接")
                except Exception as e:
                    print(f"断开离线账号WebSocket连接失败: {user_name}, 错误: {e}")
    
    def _connect_websocket_for_new_user(self, user_name: str):
        """为新登录用户建立WebSocket连接（在子线程中执行）"""
        try:
            http_client.connect_websocket(
                user_name,
                message_callback=self.on_websocket_message,
                status_callback=self.on_websocket_status_changed
            )
            print(f"已为新登录账号 {user_name} 建立WebSocket连接")
        except Exception as e:
            print(f"为新登录账号建立WebSocket连接失败: {user_name}, 错误: {e}")
    
    def _wake_up_account_worker(self, row: int, user_name: str, nick_name: str):
        """在子线程中执行唤醒登录"""
        try:
            print(f"开始唤醒账号: {user_name}")
            
            # 获取当前代理配置名称
            current_proxy = self.get_current_proxy_name()
            wake_resp = http_client.wake_up_login(user_name, current_proxy)
            print(f"唤醒登录回复 - {user_name}: {wake_resp}")
            
            # 检查唤醒登录是否成功
            wake_success = wake_resp.get("Success", False) and wake_resp.get("Code", -1) == 0
            if wake_success:
                uuid = wake_resp.get("Data", {}).get("Uuid", "")
                exprired_time = wake_resp.get("Data", {}).get("ExpiredTime", 0)
                print(f"uuid: {uuid}, exprired_time: {exprired_time}")
                if uuid and exprired_time > 0:
                    # 开始定时检查二维码状态
                    self._start_qr_status_check(row, user_name, uuid, exprired_time)
                    return
            print(f"账号 {user_name} 唤醒登录失败")
            self.wake_up_result_ready.emit(row, user_name, False)
                
        except Exception as e:
            print(f"唤醒登录请求失败: {user_name}, 错误: {e}")
            self.wake_up_result_ready.emit(row, user_name, False)
    
    def _start_qr_status_check(self, row: int, user_name: str, uuid: str, expired_time: int):
        """开始定时检查二维码状态"""
        print(f"开始定时检查二维码状态 - {user_name}, uuid: {uuid}, 过期时间: {expired_time}秒")
        
        # 保存检查数据
        self.qr_check_data[user_name] = {
            'row': row,
            'uuid': uuid,
            'start_time': time.time(),
            'expired_time': expired_time
        }
        
        # 在主线程中创建定时器
        self.qr_check_timer_ready.emit(user_name, row, uuid, expired_time)
    
    def _check_qr_status(self, user_name: str):
        """检查二维码状态"""
        if user_name not in self.qr_check_data:
            return
        
        data = self.qr_check_data[user_name]
        row = data['row']
        uuid = data['uuid']
        start_time = data['start_time']
        expired_time = data['expired_time']
        device_id = data['device_id']
        
        # 检查是否超时
        current_time = time.time()
        if current_time - start_time > expired_time:
            print(f"二维码检查超时 - {user_name}")
            self._stop_qr_status_check(user_name)
            self.qr_check_result_ready.emit(row, user_name, False)
            return
        
        try:
            # 在子线程中执行检查
            thread = threading.Thread(
                target=self._check_qr_status_worker,
                args=(user_name, row, uuid, device_id)
            )
            thread.daemon = True
            thread.start()
        except Exception as e:
            print(f"启动二维码状态检查失败: {user_name}, 错误: {e}")
    
    def _check_qr_status_worker(self, user_name: str, row: int, uuid: str, device_id: str):
        """在子线程中检查二维码状态"""
        try:
            result = http_client.check_qr_status(uuid, device_id)
            print(f"二维码状态检查 - {user_name}: {result}")
            
            # 参考qr_code_dialog.py的判断条件
            if result.get('Code') == 0 and result.get('Success') == True:
                data = result.get('Data', {})
                acct_sect_resp = data.get('acctSectResp', {})
                
                if acct_sect_resp:  # 登录成功，有账户信息
                    print(f"二维码扫描成功 - {user_name}")
                    self._stop_qr_status_check(user_name)
                    self.qr_check_result_ready.emit(row, user_name, True)
                else:
                    print(f"二维码状态检查失败 - {user_name}, 继续等待...")
            else:
                print(f"二维码状态检查失败 - {user_name}, 继续等待...")
                
        except Exception as e:
            print(f"二维码状态检查请求失败: {user_name}, 错误: {e}")
    
    def _stop_qr_status_check(self, user_name: str):
        """停止二维码状态检查"""
        if user_name in self.qr_check_timers:
            timer = self.qr_check_timers[user_name]
            timer.stop()
            timer.deleteLater()
            del self.qr_check_timers[user_name]
        
        if user_name in self.qr_check_data:
            del self.qr_check_data[user_name]
        
        print(f"停止二维码状态检查 - {user_name}")
    
    def on_qr_check_timer_ready(self, user_name: str, row: int, uuid: str, expired_time: int):
        """在主线程中创建二维码检查定时器"""
        print(f"在主线程中创建定时器 - {user_name}")
        
        # 创建定时器
        timer = QTimer(self)
        timer.timeout.connect(lambda: self._check_qr_status(user_name))
        timer.start(3000)  # 每3秒检查一次
        
        # 保存定时器
        self.qr_check_timers[user_name] = timer
        
        # 立即执行一次检查
        self._check_qr_status(user_name)
    
    def on_qr_check_result(self, row: int, user_name: str, success: bool):
        """处理二维码检查结果（在主线程中执行）"""
        if success:
            # 更新表格状态显示为在线
            status_item = QTableWidgetItem("在线")
            status_item.setFlags(status_item.flags() & ~Qt.ItemFlag.ItemIsEditable)  # 设置不可编辑
            status_item.setForeground(Qt.GlobalColor.green)
            self.account_table.setItem(row, 3, status_item)
            
            # 更新数据库状态
            db_manager.update_account_status(user_name, 1)
            
            # 更新统计信息
            self.update_stats()
            
            # 建立WebSocket连接
            try:
                http_client.connect_websocket(
                    user_name,
                    message_callback=self.on_websocket_message,
                    status_callback=self.on_websocket_status_changed
                )
                print(f"账号 {user_name} 唤醒后已建立WebSocket连接")
            except Exception as e:
                print(f"唤醒后建立WebSocket连接失败: {user_name}, 错误: {e}")
            
            QMessageBox.information(self, "唤醒成功", f"账号 {user_name} 已成功唤醒并上线")
        else:
            QMessageBox.warning(self, "唤醒失败", f"账号 {user_name} 唤醒失败，请重试")
    
    def on_wake_up_result(self, row: int, user_name: str, success: bool):
        """处理唤醒登录结果（在主线程中执行）"""
        if success:
            # 唤醒成功，等待二维码扫描
            QMessageBox.information(self, "唤醒成功", f"账号 {user_name} 唤醒成功，请扫描二维码完成登录")
        else:
            QMessageBox.warning(self, "唤醒失败", f"账号 {user_name} 唤醒失败，请重试")
    
    def manage_websocket_connections(self):
        """更新WebSocket连接状态显示"""
        try:
            # 获取所有WebSocket连接状态，添加超时保护
            websocket_status = {}
            try:
                websocket_status = http_client.get_all_websocket_status()
            except Exception as e:
                print(f"获取WebSocket状态时出错: {e}")
                websocket_status = {}
            
            # 统计在线账号数量
            online_count = 0
            connected_count = 0
            
            try:
                row_count = self.account_table.rowCount()
                for row in range(row_count):
                    status_item = self.account_table.item(row, 3)
                    if status_item and status_item.text() == "在线":
                        online_count += 1
            except Exception as e:
                print(f"统计在线账号时出错: {e}")
                online_count = 0
            
            # 统计已连接的WebSocket数量
            try:
                connected_count = len([user for user, status in websocket_status.items() if status.get('connected', False)])
            except Exception as e:
                print(f"统计WebSocket连接数时出错: {e}")
                connected_count = 0
            
            # 更新WebSocket状态显示
            try:
                if online_count == 0:
                    self.websocket_status_label.setText("WebSocket: 无在线账号")
                    StyleManager.set_label_style(self.websocket_status_label, "status-muted")
                elif connected_count == online_count:
                    self.websocket_status_label.setText(f"WebSocket: 已连接 ({connected_count}/{online_count})")
                    StyleManager.set_label_style(self.websocket_status_label, "status-success")
                else:
                    self.websocket_status_label.setText(f"WebSocket: 连接中 ({connected_count}/{online_count})")
                    StyleManager.set_label_style(self.websocket_status_label, "status-warning")
            except Exception as e:
                print(f"更新WebSocket状态显示时出错: {e}")
                
        except Exception as e:
            print(f"manage_websocket_connections方法出错: {e}")
            # 设置默认状态
            try:
                self.websocket_status_label.setText("WebSocket: 状态异常")
                StyleManager.set_label_style(self.websocket_status_label, "status-danger")
            except:
                pass
    
    def on_websocket_message(self, user_name: str, message: str):
        """处理WebSocket消息"""
        # 这里可以添加消息处理逻辑，比如解析消息内容、更新UI等
        
    def on_websocket_status_changed(self, user_name: str, is_connected: bool):
        """处理WebSocket连接状态变化"""
        try:
            status_text = "已连接" if is_connected else "已断开"
            print(f"WebSocket状态变化 - {user_name}: {status_text}")
            
            # 更新状态显示
            connected_users = {}
            try:
                connected_users = http_client.get_all_websocket_status()
            except Exception as e:
                print(f"获取WebSocket状态时出错: {e}")
                connected_users = {}
            
            online_accounts = []
            
            # 获取在线账号数量
            try:
                row_count = self.account_table.rowCount()
                for row in range(row_count):
                    status_item = self.account_table.item(row, 3)
                    if status_item and status_item.text() == "在线":
                        online_accounts.append(row)
            except Exception as e:
                print(f"获取在线账号时出错: {e}")
                online_accounts = []
            
            online_count = len(online_accounts)
            connected_count = 0
            
            try:
                connected_count = len([user for user, status in connected_users.items() if status.get('connected', False)])
            except Exception as e:
                print(f"统计连接数时出错: {e}")
                connected_count = 0
            
            try:
                if online_count == 0:
                    self.websocket_status_label.setText("WebSocket: 无在线账号")
                    StyleManager.set_label_style(self.websocket_status_label, "status-muted")
                elif connected_count == online_count:
                    self.websocket_status_label.setText(f"WebSocket: 已连接 ({connected_count}/{online_count})")
                    StyleManager.set_label_style(self.websocket_status_label, "status-success")
                else:
                    self.websocket_status_label.setText(f"WebSocket: 连接中 ({connected_count}/{online_count})")
                    StyleManager.set_label_style(self.websocket_status_label, "status-warning")
            except Exception as e:
                print(f"更新WebSocket状态显示时出错: {e}")
                
        except Exception as e:
            print(f"on_websocket_status_changed方法出错: {e}")
            # 设置默认状态
            try:
                self.websocket_status_label.setText("WebSocket: 状态异常")
                StyleManager.set_label_style(self.websocket_status_label, "status-danger")
            except:
                pass
    
    def account_table_mouse_press_event(self, event):
        """处理表格鼠标点击事件"""
        # 获取点击位置对应的item
        item = self.account_table.itemAt(event.pos())
        
        # 如果点击的是空白区域（没有item），清除选择
        if item is None:
            self.account_table.clearSelection()
            # 禁用所有按钮
            self.logout_btn.setEnabled(False)
            self.wake_up_btn.setEnabled(False)
            self.delete_btn.setEnabled(False)
        else:
            # 如果点击的是有效item，调用原始的鼠标事件处理
            QTableWidget.mousePressEvent(self.account_table, event)
    
    def on_account_selection_changed(self):
        """处理账号表格选择变化"""
        selected_rows = self.account_table.selectionModel().selectedRows()
        has_selection = len(selected_rows) > 0
        
        # 启用/禁用按钮
        self.logout_btn.setEnabled(has_selection)
        self.wake_up_btn.setEnabled(has_selection)
        self.delete_btn.setEnabled(has_selection)
        
        # 如果有选中项，检查账号状态来决定唤醒按钮的可用性
        if has_selection:
            row = selected_rows[0].row()
            accounts = db_manager.get_all_accounts()
            if row < len(accounts):
                account = accounts[row]
                user_name = account.get('user_name', '')
                
                # 检查当前账号状态
                status_item = self.account_table.item(row, 3)
                if status_item and status_item.text() == "离线":
                    self.wake_up_btn.setEnabled(True)
                    self.wake_up_btn.setText("唤醒登录")
                else:
                    self.wake_up_btn.setEnabled(False)
                    self.wake_up_btn.setText("账号在线")
    
    def wake_up_selected_account(self):
        """唤醒选中的账号"""
        selected_rows = self.account_table.selectionModel().selectedRows()
        if not selected_rows:
            QMessageBox.warning(self, "提示", "请先选择要唤醒的账号")
            return
        
        # 获取选中的行
        row = selected_rows[0].row()
        
        # 从数据库获取账号信息
        accounts = db_manager.get_all_accounts()
        if row >= len(accounts):
            QMessageBox.warning(self, "错误", "选中的账号信息无效")
            return
        
        account = accounts[row]
        user_name = account.get('user_name', '')
        nick_name = account.get('nick_name', '') or user_name
        
        # 检查账号状态
        status_item = self.account_table.item(row, 3)
        if status_item and status_item.text() == "在线":
            QMessageBox.information(self, "提示", f"账号 {nick_name} 当前已在线，无需唤醒")
            return
        
        # 确认对话框
        reply = QMessageBox.question(
            self, 
            "确认唤醒", 
            f"确定要唤醒账号 {nick_name} 吗？\n\n用户名: {user_name}",
            QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
            QMessageBox.StandardButton.No
        )
        
        if reply == QMessageBox.StandardButton.Yes:
            # 在子线程中执行唤醒登录
            thread = threading.Thread(
                target=self._wake_up_account_worker,
                args=(row, user_name, nick_name)
            )
            thread.daemon = True
            thread.start()
    
    def delete_selected_account(self):
        """删除选中的账号"""
        selected_rows = self.account_table.selectionModel().selectedRows()
        if not selected_rows:
            QMessageBox.warning(self, "提示", "请先选择要删除的账号")
            return
        
        # 获取选中的行
        row = selected_rows[0].row()
        
        # 从数据库获取账号信息
        accounts = db_manager.get_all_accounts()
        if row >= len(accounts):
            QMessageBox.warning(self, "错误", "选中的账号信息无效")
            return
        
        account = accounts[row]
        user_name = account.get('user_name', '')
        nick_name = account.get('nick_name', '') or user_name
        
        # 检查账号状态，如果在线需要先退出
        status_item = self.account_table.item(row, 3)
        if status_item and status_item.text() == "在线":
            reply = QMessageBox.question(
                self, 
                "账号在线", 
                f"账号 {nick_name} 当前在线，删除前需要先退出登录。\n\n是否继续？",
                QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
                QMessageBox.StandardButton.No
            )
            if reply == QMessageBox.StandardButton.Yes:
                # 先退出登录，然后删除
                self._delete_account_with_logout(row, user_name, nick_name)
            return
        
        # 确认删除对话框
        reply = QMessageBox.question(
            self, 
            "确认删除", 
            f"确定要删除账号 {nick_name} 吗？\n\n用户名: {user_name}\n\n此操作不可恢复！",
            QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
            QMessageBox.StandardButton.No
        )
        
        if reply == QMessageBox.StandardButton.Yes:
            # 在子线程中执行删除操作
            thread = threading.Thread(
                target=self._delete_account_worker,
                args=(row, user_name, nick_name)
            )
            thread.daemon = True
            thread.start()
    
    def logout_selected_account(self):
        """退出选中的账号"""
        selected_rows = self.account_table.selectionModel().selectedRows()
        if not selected_rows:
            QMessageBox.warning(self, "提示", "请先选择要退出的账号")
            return
        
        # 获取选中的行
        row = selected_rows[0].row()
        
        # 从数据库获取账号信息
        accounts = db_manager.get_all_accounts()
        if row >= len(accounts):
            QMessageBox.warning(self, "错误", "选中的账号信息无效")
            return
        
        account = accounts[row]
        user_name = account.get('user_name', '')
        nick_name = account.get('nick_name', '') or user_name
        
        # 确认对话框
        reply = QMessageBox.question(
            self, 
            "确认退出", 
            f"确定要退出账号 {nick_name} 吗？\n\n用户名: {user_name}",
            QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
            QMessageBox.StandardButton.No
        )
        
        if reply == QMessageBox.StandardButton.Yes:
            # 在子线程中执行退出登录
            thread = threading.Thread(
                target=self._logout_account_worker,
                args=(row, user_name, nick_name)
            )
            thread.daemon = True
            thread.start()
    
    def _logout_account_worker(self, row: int, user_name: str, nick_name: str):
        """在子线程中执行退出登录"""
        try:
            print(f"开始退出账号: {user_name}")
            
            # 调用退出登录API
            resp = http_client.logout(user_name)
            print(f"退出登录回复 - {user_name}: {resp}")
            
            # 检查退出是否成功
            # Code为0表示成功，Code为-13表示"用户可能退出"也视为成功
            logout_success = (resp.get("Success", False) and resp.get("Code", -1) == 0 ) or (not resp.get("Success", False) and resp.get("Code", -1) == -13)
            
            if logout_success:
                code = resp.get("Code", -1)
                if code == 0:
                    print(f"账号 {user_name} 退出登录成功")
                elif code == -13:
                    print(f"账号 {user_name} 退出登录成功（用户可能退出）")
                else:
                    print(f"账号 {user_name} 退出登录成功（状态码: {code}）")
                
                # 断开WebSocket连接
                try:
                    http_client.disconnect_websocket(user_name)
                    print(f"已断开账号 {user_name} 的WebSocket连接")
                except Exception as ws_e:
                    print(f"断开WebSocket连接失败: {user_name}, 错误: {ws_e}")
                
                # 更新数据库状态为离线
                db_manager.update_account_status(user_name, 0)
                print(f"账号 {user_name} 状态已更新为离线")
                
                # 发送信号更新UI
                self.logout_result_ready.emit(row, user_name, True)
            else:
                print(f"账号 {user_name} 退出登录失败")
                self.logout_result_ready.emit(row, user_name, False)
                
        except Exception as e:
            print(f"退出登录请求失败: {user_name}, 错误: {e}")
            self.logout_result_ready.emit(row, user_name, False)
    
    def on_logout_result(self, row: int, user_name: str, success: bool):
        """处理退出登录结果（在主线程中执行）"""
        if success:
            # 更新表格状态显示为离线
            status_item = QTableWidgetItem("离线")
            status_item.setFlags(status_item.flags() & ~Qt.ItemFlag.ItemIsEditable)  # 设置不可编辑
            status_item.setForeground(Qt.GlobalColor.red)
            self.account_table.setItem(row, 3, status_item)
            
            # 更新统计信息
            self.update_stats()
            
            # 更新按钮状态
            self.wake_up_btn.setEnabled(True)
            self.wake_up_btn.setText("唤醒登录")
            
            # 清除选择
            self.account_table.clearSelection()
            self.logout_btn.setEnabled(False)
            self.wake_up_btn.setEnabled(False)
            self.delete_btn.setEnabled(False)
            
            QMessageBox.information(self, "退出成功", f"账号 {user_name} 已成功退出登录")
        else:
            QMessageBox.warning(self, "退出失败", f"账号 {user_name} 退出登录失败，请重试")
    
    def _delete_account_with_logout(self, row: int, user_name: str, nick_name: str):
        """先退出登录再删除账号"""
        # 先执行退出登录
        thread = threading.Thread(
            target=self._logout_and_delete_worker,
            args=(row, user_name, nick_name)
        )
        thread.daemon = True
        thread.start()
    
    def _logout_and_delete_worker(self, row: int, user_name: str, nick_name: str):
        """先退出登录再删除账号的工作线程"""
        try:
            print(f"开始退出并删除账号: {user_name}")
            
            # 先退出登录
            resp = http_client.logout(user_name)
            print(f"退出登录回复 - {user_name}: {resp}")
            
            # 检查退出是否成功
            logout_success = (resp.get("Success", False) and resp.get("Code", -1) == 0) or (not resp.get("Success", False) and resp.get("Code", -1) == -13)
            
            if logout_success:
                print(f"账号 {user_name} 退出登录成功，开始删除")
                
                # 断开WebSocket连接
                try:
                    http_client.disconnect_websocket(user_name)
                    print(f"已断开账号 {user_name} 的WebSocket连接")
                except Exception as ws_e:
                    print(f"断开WebSocket连接失败: {user_name}, 错误: {ws_e}")
                
                # 删除账号
                if db_manager.delete_account(user_name):
                    print(f"账号 {user_name} 已从数据库删除")
                    self.delete_result_ready.emit(row, user_name, True)
                else:
                    print(f"从数据库删除账号失败: {user_name}")
                    self.delete_result_ready.emit(row, user_name, False)
            else:
                print(f"账号 {user_name} 退出登录失败，无法删除")
                self.delete_result_ready.emit(row, user_name, False)
                
        except Exception as e:
            print(f"退出并删除账号失败: {user_name}, 错误: {e}")
            self.delete_result_ready.emit(row, user_name, False)
    
    def _delete_account_worker(self, row: int, user_name: str, nick_name: str):
        """在子线程中执行删除账号"""
        try:
            print(f"开始删除账号: {user_name}")
            
            # 断开WebSocket连接（如果存在）
            try:
                http_client.disconnect_websocket(user_name)
                print(f"已断开账号 {user_name} 的WebSocket连接")
            except Exception as ws_e:
                print(f"断开WebSocket连接失败: {user_name}, 错误: {ws_e}")
            
            # 从数据库删除账号
            if db_manager.delete_account(user_name):
                print(f"账号 {user_name} 已从数据库删除")
                self.delete_result_ready.emit(row, user_name, True)
            else:
                print(f"从数据库删除账号失败: {user_name}")
                self.delete_result_ready.emit(row, user_name, False)
                
        except Exception as e:
            print(f"删除账号失败: {user_name}, 错误: {e}")
            self.delete_result_ready.emit(row, user_name, False)
    
    def on_delete_result(self, row: int, user_name: str, success: bool):
        """处理删除账号结果（在主线程中执行）"""
        if success:
            # 更新账号表格
            self.update_account_table()
            
            # 清除选择
            self.account_table.clearSelection()
            self.logout_btn.setEnabled(False)
            self.wake_up_btn.setEnabled(False)
            self.delete_btn.setEnabled(False)
            
            QMessageBox.information(self, "删除成功", f"账号 {user_name} 已成功删除")
        else:
            QMessageBox.warning(self, "删除失败", f"账号 {user_name} 删除失败，请重试")
    
    def on_consent_finished(self):
        """处理群邀请同意完成信号"""
        # 更新账号表格以显示最新的进群统计
        self.update_account_table()
        print("群邀请处理完成，已更新账号表格")
    
    def on_account_item_changed(self, item):
        """处理账号表格item变化（主要是备注列的编辑）"""
        try:
            row = item.row()
            column = item.column()
            
            # 只处理备注列（第4列）的编辑
            if column == 4:
                # 获取用户名
                accounts = db_manager.get_all_accounts()
                if row < len(accounts):
                    account = accounts[row]
                    user_name = account.get('user_name', '')
                    new_remark = item.text()
                    
                    # 这里可以添加保存备注到数据库的逻辑
                    # 目前暂时只打印，您可以根据需要扩展数据库字段
                    print(f"用户 {user_name} 的备注已修改为: {new_remark}")
                    
                    # 如果需要保存到数据库，可以添加以下代码：
                    # db_manager.update_account_remark(user_name, new_remark)
                    
        except Exception as e:
            print(f"处理账号item变化失败: {e}") 